#include "appenderfactory.h"
#include "consoleappender.h"
#include "fileappender.h"
#include "tcpappender.h"
#include "udpappender.h"
#include "qtexteditappender.h"
#include "qplaintexteditappender.h"
#include <QCoreApplication>
#include <iostream>


AppenderFactory * AppenderFactory ::m_instance = nullptr;

AppenderFactory ::AppenderFactory (QObject *parent) : QObject(parent) {
    // 注册所有Appender子类的工厂函数（关键：关联类型与创建逻辑）
    registerCreator(AppenderType::Console, [](const AppenderParams& params, LogLevel level) {
        Q_UNUSED(params); // ConsoleAppender无需额外参数
        return new ConsoleAppender(level);
    });

    registerCreator(AppenderType::File, [](const AppenderParams& params, LogLevel level) {
        // FileAppender需要"path"和"baseName"参数
        QString path = params.value("path").toString();
        return new FileAppender(level, path);
    });

    registerCreator(AppenderType::Tcp, [](const AppenderParams& params, LogLevel level) {
        // TcpAppender需要"ip"和"port"参数
        QString ip = params.value("ip").toString();
        quint16 port = params.value("port").toUInt();
        return new TcpAppender(level, ip, port);
    });

    // 其他Appender（Udp/QTextEdit等）的工厂函数类似，按实际参数注册
    registerCreator(AppenderType::Udp, [](const AppenderParams& params, LogLevel level) {
        QString ip = params.value("ip").toString();
        quint16 port = params.value("port").toUInt();
        return new UdpAppender(level, ip, port);
    });

    registerCreator(AppenderType::QPlainTextEdit, [](const AppenderParams& params, LogLevel level) {
        QPlainTextEdit* plainTextEdit = params.value("plainTextEdit").value<QPlainTextEdit*>();
        return new QPlainTextEditAppender(level,plainTextEdit);
    });

    registerCreator(AppenderType::QTextEdit, [](const AppenderParams& params, LogLevel level) {
        QTextEdit* textEdit = params.value("textEdit").value<QTextEdit*>();
        return new QTextEditAppender(level,textEdit);
    });


}

AppenderFactory ::~AppenderFactory () {
    qInstallMessageHandler(nullptr);
    QMutexLocker locker(&m_mutex);
    // 销毁所有活跃实例
    qDeleteAll(m_activeAppenders);
    m_activeAppenders.clear();
}

AppenderFactory * AppenderFactory ::instance() {
    if (!m_instance) {
        static QMutex mutex;
        QMutexLocker locker(&mutex);
        if (!m_instance) {
            m_instance = new AppenderFactory (QCoreApplication::instance());
        }
    }
    return m_instance;
}

void AppenderFactory::startRedirect()
{
    // 安装Qt日志重定向
    qInstallMessageHandler(qtMessageHandler);
}

void AppenderFactory::stopRedirect()
{
    // 安装Qt日志重定向
    qInstallMessageHandler(nullptr);
}

void AppenderFactory ::registerCreator(AppenderType type, AppenderCreator  factory) {
    QMutexLocker locker(&m_mutex);
    m_factories[type] = factory;
}

bool AppenderFactory ::addAppender(const QString& name, AppenderType type,
                                const AppenderParams& params, LogLevel level) {
    QMutexLocker locker(&m_mutex);
    if (m_metaMap.contains(name)) {
        std::cerr <<"Appender已存在："<<name.toStdString()<<std::endl;
        return false;
    }
    // 保存元信息（默认禁用，需手动启用）
    m_metaMap[name] = {name, type, params, level, false};
    return true;
}

void AppenderFactory ::setAppenderEnabled(const QString& name, bool enabled) {
    QMutexLocker locker(&m_mutex);
    if (!m_metaMap.contains(name)) return;

    AppenderMeta& meta = m_metaMap[name];
    if (meta.enabled == enabled) return; // 状态未变，无需操作

    meta.enabled = enabled; // 更新元信息中的启用状态

    if (enabled) {
        // 启用：创建实例并加入活跃列表
        BaseAppender* appender = createAppender(meta);
        if (appender) {
            m_activeAppenders[name] = appender;
        }
    } else {
        // 禁用：从活跃列表移除并销毁实例
        BaseAppender* appender = m_activeAppenders.take(name);
        if (appender) {
            appender->deleteLater();
        }
    }
}

void AppenderFactory::setAppenderEnabled(AppenderType type, bool enabled)
{
    // 使用 const_iterator 直接遍历键值对，无需生成临时 keys() 列表
    for (QMap<QString, AppenderMeta>::const_iterator it = m_metaMap.constBegin();
         it != m_metaMap.constEnd(); ++it) {
        if (it.value().type == type) {
            setAppenderEnabled(it.value().name,enabled);
        }
    }
}

bool AppenderFactory ::isAppenderEnabled(const QString& name) {
    QMutexLocker locker(&m_mutex);
    return m_metaMap.value(name).enabled;
}

void AppenderFactory ::setAllLogLevel(LogLevel level) {
    QMutexLocker locker(&m_mutex);
    // 更新所有元信息的级别
    for (auto& meta : m_metaMap) {
        meta.level = level;
    }
    // 同步更新活跃实例的级别
    for (auto appender : std::as_const(m_activeAppenders)) {
        appender->setLevel(level);
    }
}

void AppenderFactory ::log(LogLevel level, const QString& msg) {
    QMutexLocker locker(&m_mutex);

    // 遍历所有活跃实例输出日志（使用格式化后的msg）
    for (auto appender :std::as_const(m_activeAppenders)) {
        if (appender) {
            appender->append(level, msg); // 这里的msg如果是qtMessageHandler传来的，已经是格式化后的
        }
    }
}

BaseAppender* AppenderFactory ::createAppender(const AppenderMeta& meta) {
    // 检查工厂是否存在
    if (!m_factories.contains(meta.type)) {
        std::cerr <<"未注册的Appender类型："<< (int)meta.type<<std::endl;
        return nullptr;
    }
    // 调用工厂函数创建实例
    return m_factories[meta.type](meta.params, meta.level);
}

void AppenderFactory ::qtMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg) {
    // LogLevel level = qtTypeToLogLevel(type);
    // QString logMsg = QString("[%1:%2] %3")
    //                      .arg(context.file ? context.file : "unknown")
    //                      .arg(context.line)
    //                      .arg(msg);

    Q_UNUSED(context);
    // 1. 转换日志级别
    LogLevel level = qtTypeToLogLevel(type);
    QString levelStr = logLevelToString(level);

    // 2. 获取当前日期时间（精确到毫秒）
    QString datetime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");

    // 3. 格式化日志：[level][datetime]msg
    QString logMsg = QString("[%1][%2]%3").arg(levelStr,datetime,msg);


    instance()->log(level, logMsg);

    if (type == QtFatalMsg) {
        abort();
    }
}

QList<QString> AppenderFactory::getAllAppenders()
{
    return m_metaMap.keys();
}

QList<QString> AppenderFactory::getActiveAppenders()
{
    return m_activeAppenders.keys();
}

QList<AppenderType> AppenderFactory::getAllAppenderType()
{
    return m_factories.keys();
}

QList<AppenderType> AppenderFactory::getActiveAppenderType()
{
    QList<AppenderType> result;
    // 使用迭代器遍历QMap，明确获取键和值
    for (auto it = m_activeAppenders.constBegin(); it != m_activeAppenders.constEnd(); ++it) {
        const QString& appenderName = it.key(); // 键：Appender名称
        // 防御性检查：确保元信息存在
        if (m_metaMap.contains(appenderName)) {
            result.append(m_metaMap[appenderName].type);
        }
    }
    return result;
}

QString AppenderFactory::getAppenderName(AppenderType type)
{
    // 使用 const_iterator 直接遍历键值对，无需生成临时 keys() 列表
    for (QMap<QString, AppenderMeta>::const_iterator it = m_metaMap.constBegin();
         it != m_metaMap.constEnd(); ++it) {
        if (it.value().type == type) {
            return it.key(); // 返回匹配类型的 Appender 名称
        }
    }
    return QString(); // 未找到返回空字符串
}

LogLevel AppenderFactory ::qtTypeToLogLevel(QtMsgType type) {
    switch (type) {
    case QtDebugMsg:    return LogLevel::Debug;
    case QtInfoMsg:     return LogLevel::Info;
    case QtWarningMsg:  return LogLevel::Warning;
    case QtCriticalMsg: return LogLevel::Error;
    case QtFatalMsg:    return LogLevel::Fatal;
    default:            return LogLevel::Debug;
    }
}

QString AppenderFactory ::logLevelToString(LogLevel level)
{
    switch (level) {
    case LogLevel::Debug:    return "Debug";
    case LogLevel::Info:     return "Info";
    case LogLevel::Warning:  return "Warning";
    case LogLevel::Error:    return "Error";
    case LogLevel::Fatal:    return "Fatal";
    default:                 return "Unknown";
    }
}
